package ygstudio.xue.de.activity;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

import ygstudio.xue.de.Constants;
import ygstudio.xue.de.R;
import ygstudio.xue.de.RuntimeUtils;
import ygstudio.xue.de.db.DB;
import ygstudio.xue.de.edit.Edit;
import ygstudio.xue.de.home.Home;
import ygstudio.xue.de.list.BaseData;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.text.Html;
import android.text.Spanned;
import android.text.method.ScrollingMovementMethod;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.RatingBar;
import android.widget.RatingBar.OnRatingBarChangeListener;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

public class Detail extends Activity {

	// 进度条处理
	private class MySeekbar implements OnSeekBarChangeListener {
		public void onProgressChanged(SeekBar seekBar, int progress,
				boolean fromUser) {
			if (progress + mediaStart >= mediaEnd && mediaEnd > 10) {
				playerStop();
				if (isAutoLauf) {
					gotoNext();
				}
				// isChanging = true;
			} else {
				isChanging = false;
			}
		}

		public void onStartTrackingTouch(SeekBar seekBar) {
			// 是指在我们开始拖动SeekBar游标的瞬间所触发的回调函数。也就是当我们用手指按下游标的那一瞬间
			isChanging = true;
		}

		public void onStopTrackingTouch(SeekBar seekBar) {
			// 是在拖动SeekBar游标停止的那一瞬间所触发的回调函数
			mediaPlayer.seekTo(getSeekbarPosition());
			isChanging = false;
		}

	}

	private BaseData baseData = new BaseData();

	private TextView contentView;
	private SQLiteDatabase db;

	private String htmlStr;
	private ArrayList<String> idList;

	private boolean isChanging = false;
	private boolean isTestMode, isAutoLauf, isNextPlay;
	private MediaPlayer mediaPlayer;
	private int mediaStart, mediaEnd;

	private Uri mp3Uri;
	private TextToSpeech mTextToSpeech = null;

	private Timer mTimer;

	private TimerTask mTimerTask;

	private ImageButton play, stop;

	private int pos;
	private Button pre, next;
	private RatingBar ratingBar;

	private SeekBar seekBar;

	private SharedPreferences sharedPreferences;
	private SharedPreferences.Editor sharedPreferencesEditor;

	private Spanned spanStr;

	private int finishCount = 0;

	private MenuItem testItem, autoLaufItem, nextPlayItem;

	private void changeTextStyle(boolean b) {
		if (b) {
			String txt = htmlStr.replaceAll("ff0000", "F0F0F0");
			txt = txt.replaceAll("0000ff", "F0F0F0");
			contentView.setText(Html.fromHtml(txt));
		} else {
			contentView.setText(spanStr);
		}
	}

	private int getSeekbarPosition() {
		return seekBar.getProgress() + mediaStart;
	}

	private void gotoNext() {
		testIfFinishOne();
		pos++;
		baseData.setValueOf(DB.F_ID, idList.get(pos));
		readDB();
		setNaviButtonVisible();
		if (play.isEnabled() && isNextPlay) {
			playerStart();
		}
	}

	private void mp3Init(String mp3Path) {
		mediaPlayer.reset();
		File mp3 = new File(mp3Path);
		if (!mp3.exists()) {
			setMp3ButtonVisible(false);
			mp3Uri = null;
		} else {
			mp3Uri = Uri.fromFile(mp3);
			try {
				mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
				mediaPlayer.setDataSource(getApplicationContext(), mp3Uri);
				mediaPlayer.prepare();// TODO: setOnPreparedListener
										// 加载完才能播放和getduration
				mediaPlayer.seekTo(mediaStart);
				setMp3ButtonVisible(true);
			} catch (IllegalStateException e1) {
				e1.printStackTrace();
			} catch (IOException e1) {
				e1.printStackTrace();
			}

		}
	}

	@Override
	public void onBackPressed() {
		returnToHome();
		super.onBackPressed();

	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.detail);

		ActionBar actionBar = getActionBar();
		actionBar.setDisplayShowHomeEnabled(false);
		actionBar.setDisplayShowTitleEnabled(false);
		actionBar.setDisplayHomeAsUpEnabled(true);

		seekBar = (SeekBar) findViewById(R.id.detail_mp3_seekbar);
		seekBar.setOnSeekBarChangeListener(new MySeekbar());

		contentView = (TextView) findViewById(R.id.detailTextContent);
		contentView.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				finishCount++;
				if (!isTestMode) {
					return false;
				}
				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					changeTextStyle(false);
				} else if (event.getAction() == MotionEvent.ACTION_UP) {
					changeTextStyle(true);
				}
				return false;
			}
		});

		Bundle bundle = getIntent().getExtras();
		baseData.setDbTable(bundle.getString(Constants.PARA_DB_TABLE));
		baseData.setValueOf(DB.F_ID, bundle.getString(Constants.PARA_DB_ID));

		db = DB.getInstance().getDB();
		pos = bundle.getInt(Constants.PARA_DB_POS, 0);
		idList = bundle.getStringArrayList(Constants.PARA_DB_IDS);

		sharedPreferences = getSharedPreferences("xuede", MODE_PRIVATE);
		sharedPreferencesEditor = sharedPreferences.edit();

		setRatingBar();
		setNaviButton();
		setMp3Button();
		setTTS();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.details_menu, menu);
		testItem = menu.findItem(R.id.detail_menuItem_test);
		autoLaufItem = menu.findItem(R.id.detail_menuItem_autolauf);
		nextPlayItem = menu.findItem(R.id.detail_menuItem_nextplay);
		// readDb之后执行
		setOptionMenuCheckBox();
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		switch (item.getItemId()) {
		case R.id.detail_menuItem_edit:
			Intent intent = new Intent(Detail.this, Edit.class);
			Bundle bundle = new Bundle();
			bundle.putSerializable("baseData", baseData);
			intent.putExtras(bundle);
			startActivity(intent);
			overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
			return true;

		case R.id.detail_menuItem_tts:
			mTextToSpeech.speak(baseData.getValueOf(DB.F_DE),
					TextToSpeech.QUEUE_FLUSH, null);

			break;
		case R.id.detail_menuItem_finish:
			setOnceFinish();
			break;
		case R.id.detail_menuItem_test:
			isTestMode = !isTestMode;
			item.setChecked(isTestMode);
			sharedPreferencesEditor.putBoolean(Constants.IS_TEST_MODE,
					isTestMode);
			sharedPreferencesEditor.commit();
			changeTextStyle(isTestMode);
			break;
		case R.id.detail_menuItem_autolauf:
			isAutoLauf = !isAutoLauf;
			item.setChecked(isAutoLauf);
			sharedPreferencesEditor.putBoolean(Constants.IS_AUTO_LAUF,
					isAutoLauf);
			sharedPreferencesEditor.commit();
			break;
		case R.id.detail_menuItem_nextplay:
			isNextPlay = !isNextPlay;
			item.setChecked(isNextPlay);
			sharedPreferencesEditor.putBoolean(Constants.IS_NEXT_PLAY,
					isNextPlay);
			sharedPreferencesEditor.commit();
			break;
		}
		return super.onMenuItemSelected(featureId, item);
	}

	private void setOnceFinish() {
		int i;
		String s = baseData.getValueOf(DB.F_COUNT);
		if (s.isEmpty()) {
			i = 0;
		} else {
			i = Integer.parseInt(s);
		}
		i++;

		baseData.setValueOf(DB.F_COUNT, i + "");
		if (baseData.updateDb(db) > 0) {
			Toast t = Toast.makeText(getApplicationContext(), "完成 " + i + "次",
					Toast.LENGTH_SHORT);
			t.show();
		}
	}

	@Override
	protected void onResume() {
		readDB();
		super.onResume();
	}

	private void playerPause() {
		// Toast.makeText(
		// getApplicationContext(),
		// "Pausing sound " + mediaStart + " "
		// + mediaPlayer.getCurrentPosition(),
		// Toast.LENGTH_SHORT).show();
		mediaPlayer.pause();
		play.setImageResource(R.drawable.mp3_play);
	}

	private void playerStart() {
		isChanging = false;
		play.setImageResource(R.drawable.mp3_pause);
		mediaPlayer.start();
		mediaPlayer.seekTo(getSeekbarPosition());
		if (mTimer == null) {
			mTimer = new Timer();
			mTimerTask = new TimerTask() {
				@Override
				public void run() {
					int curr = mediaPlayer.getCurrentPosition();

					if (isChanging == true) {
						return;
					}
					if (mediaPlayer.isPlaying()) {
						seekBar.setProgress(curr - mediaStart);
					}
				}
			};
			mTimer.schedule(mTimerTask, 0, 10);
		}

	}

	private void playerStop() {
		mTextToSpeech.stop();

		mediaPlayer.stop();
		seekBar.setProgress(0);
		try {
			mediaPlayer.prepare();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		play.setImageResource(R.drawable.mp3_play);
	}

	private void readDB() {
		mediaStart = 0;
		mediaEnd = 0;
		finishCount = 0;
		mediaPlayer = RuntimeUtils.getInstance().getMediaPlayer();
		Cursor cursor = db
				.rawQuery("Select * from " + baseData.getDbTable()
						+ " where _id=?",
						new String[] { baseData.getValueOf(DB.F_ID) });

		if (cursor.moveToFirst()) {
			baseData.updateByCursor(cursor);
			String ms = baseData.getValueOf(DB.F_MEDIA_START);
			String me = baseData.getValueOf(DB.F_MEDIA_END);
			if (ms != null && !ms.isEmpty()) {
				mediaStart = (int) (Float.parseFloat(ms) / 44.42);
			}

			if (me != null && !me.isEmpty()) {
				mediaEnd = (int) (Float.parseFloat(me) / 44.42);
			}

			if (mediaEnd < 100) {
				mediaEnd = mediaPlayer.getDuration();
			}

			seekBar.setMax(mediaEnd - mediaStart);

			String de = baseData.getValueOf(DB.F_DE);
			String title = baseData.getValueOf(DB.F_TITLE);
			String cn = baseData.getValueOf(DB.F_CN);
			String notiz = baseData.getValueOf(DB.F_NOTIZ);
			String itemContent = "";
			String dt = baseData.getDbTable();
			if (dt == DB.TABLE_SATZ) {
				itemContent = de;
			} else {
				itemContent = title + "\n" + de;
			}
			if (cn != null && !cn.isEmpty()) {
				itemContent += "\n" + cn;
			}
			if (notiz != null && !notiz.isEmpty()) {
				itemContent += "\n" + notiz;
			}

			String mp3Path = baseData.getValueOf(DB.F_MEDIA);

			if (mp3Path.isEmpty()) {
				setMp3ButtonVisible(false);
			} else {
				mp3Init(RuntimeUtils.getInstance().getSdMp3Dir() + "/"
						+ mp3Path);
			}
			htmlStr = itemContent;
			spanStr = Html.fromHtml(itemContent);
			contentView.setText(spanStr);
			contentView.setMovementMethod(new ScrollingMovementMethod());

			String rating = baseData.getValueOf(DB.F_RATING);
			if (rating == null || rating.isEmpty()) {
				ratingBar.setRating(0);
			} else {
				float f = Float.parseFloat(rating);
				ratingBar.setRating(f);
			}
		}
		cursor.close();
		changeTextStyle(isTestMode);
	}

	private void returnToHome() {
		testIfFinishOne();
		mTextToSpeech.stop();
		mTextToSpeech.shutdown();
		mediaPlayer.reset();
		Intent intent = new Intent(Detail.this, Home.class);
		intent.putExtra("selectedPos", pos);
		setResult(0, intent);
		finish();
		overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out);
	}

	private void setMp3Button() {
		play = (ImageButton) findViewById(R.id.mp3Play);
		stop = (ImageButton) findViewById(R.id.mp3Stop);

		play.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {

				if (mediaPlayer.isPlaying()) {
					playerPause();

				} else {
					playerStart();
					finishCount++;
				}

			}

		});
		stop.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				playerStop();
			}
		});
	}

	private void setMp3ButtonVisible(boolean b) {
		int i = b ? View.VISIBLE : View.INVISIBLE;
		play.setVisibility(i);
		stop.setVisibility(i);

		if (b) {
			seekBar.setVisibility(View.VISIBLE);
		} else {
			seekBar.setVisibility(View.GONE);
		}
	}

	private void testIfFinishOne() {
		if (finishCount > 2) {
			System.out.println(finishCount + "");
			setOnceFinish();
		}
	}

	private void setNaviButton() {
		pre = (Button) findViewById(R.id.detailBackButton);
		next = (Button) findViewById(R.id.detailNextButton);
		pre.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				testIfFinishOne();
				pos--;
				baseData.setValueOf(DB.F_ID, idList.get(pos));
				readDB();
				setNaviButtonVisible();
				if (play.isEnabled() && isNextPlay) {
					playerStart();
				}
			}

		});
		next.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				gotoNext();
			}

		});
		setNaviButtonVisible();
	}

	private void setNaviButtonVisible() {
		if (pos <= 0) {
			pre.setEnabled(false);
		} else {
			pre.setEnabled(true);
		}

		if (pos >= idList.size() - 1) {
			next.setEnabled(false);
		} else {
			next.setEnabled(true);
		}
	}

	private void setOptionMenuCheckBox() {
		isAutoLauf = sharedPreferences
				.getBoolean(Constants.IS_AUTO_LAUF, false);
		isTestMode = sharedPreferences
				.getBoolean(Constants.IS_TEST_MODE, false);
		isNextPlay = sharedPreferences
				.getBoolean(Constants.IS_NEXT_PLAY, false);

		autoLaufItem.setChecked(isAutoLauf);
		nextPlayItem.setChecked(isNextPlay);
		testItem.setChecked(isTestMode);
		changeTextStyle(isTestMode);
	}

	private void setRatingBar() {
		ratingBar = (RatingBar) findViewById(R.id.edit_ratingBar);

		ratingBar.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {

			@Override
			public void onRatingChanged(RatingBar ratingBar, float rating,
					boolean fromUser) {
				baseData.setValueOf(DB.F_RATING, rating + "");
				baseData.updateDb(db);
				// if (baseData.updateDb(db) > 0) {
				// Toast.makeText(getApplicationContext(), "Rating " + rating,
				// Toast.LENGTH_SHORT).show();
				// }

			}
		});
	}

	private void setTTS() {
		mTextToSpeech = new TextToSpeech(this,
				new TextToSpeech.OnInitListener() {

					@Override
					public void onInit(int status) {
						// TODO Auto-generated method stub
						if (status == TextToSpeech.SUCCESS) {
							int supported = mTextToSpeech
									.setLanguage(Locale.GERMAN);
							if ((supported != TextToSpeech.LANG_AVAILABLE)
									&& (supported != TextToSpeech.LANG_COUNTRY_AVAILABLE)) {
								Toast.makeText(Detail.this, "无法朗读",
										Toast.LENGTH_SHORT).show();
							}
						}
					}

				});
	}
}
